package perucuy.filters;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;

import perucuy.transfers.UsuarioTO;
import perucuy.utils.Constantes;
import static perucuy.utils.Constantes.*;

public class LoginFilter extends HttpServlet implements Filter {
    /**
     *
     */
    private static final long serialVersionUID = -8103836518738179697L;
    private FilterConfig filterConfig;
    private static final Logger logger = Logger.getLogger(LoginFilter.class);
    private static String INIT_PARAMETER_ROLES_PERMITIDOS = "roles";
    private List<String> rolesPermitidos;
    private String doLogin;
    private static final String INIT_PARAMETER_LOGIN = "login";
    //Handle the passed-in FilterConfig
    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
        iniciarParametros();
    }
    
    private void iniciarParametros() {
        logger.debug("iniciando parametros de filtro:" +
                filterConfig.getFilterName());
        String roles = filterConfig.getInitParameter(
                INIT_PARAMETER_ROLES_PERMITIDOS);
        if (roles != null) {
            String[] aRoles = roles.split(",");
            rolesPermitidos = Arrays.asList(aRoles);
        }
        if (roles == null || rolesPermitidos == null ||
                rolesPermitidos.size() == 0) {
            throw new RuntimeException("No se ha configurado parametro 'roles'");
        }
        
        doLogin = filterConfig.getInitParameter(INIT_PARAMETER_LOGIN);
        if (doLogin == null) {
            throw new RuntimeException("No se ha configurado parametro 'login'");
        }
    }
    
    
    //Process the request/response pair
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain filterChain) {
        HttpServletRequest req = null;
        try {
            
            HttpSession session = (req = (HttpServletRequest) request).
                    getSession();
            String url = req.getRequestURI().substring(req.getContextPath().
                    length());
            logger.debug("peticion a:" + url);
            session.setAttribute(URL_FORWARD, url);
            
            UsuarioTO usuario=(UsuarioTO) session.getAttribute(Constantes.LOGGED_USER);
            logger.debug("verificando roles");
            if (usuario == null) {
                logger.debug("no ha iniciado sesion");
                forward(doLogin, request, response);
            } else if (rolesPermitidos.indexOf(""+usuario.getTipo()) < 0) {
                logger.debug("rolesPermitidos: "+rolesPermitidos+" dato: "+usuario.getTipo()+" buscando: "+rolesPermitidos.indexOf(""+usuario.getTipo()));
                logger.debug("el rol no le corresponde");
                forward(ROL_NO_PERMITIDO_PATH, request, response);
            } else {
                logger.debug("continua con la peticion");
                filterChain.doFilter(request, response);
            }
        } catch (ServletException sx) {
            filterConfig.getServletContext().log(sx.getMessage());
        } catch (IOException iox) {
            filterConfig.getServletContext().log(iox.getMessage());
        }
    }
    
    private void forward(String fwd, ServletRequest request,
            ServletResponse response) throws IOException,
            ServletException {
        logger.debug("redireccionando a " + fwd);
        RequestDispatcher rd = request.getRequestDispatcher(fwd);
        rd.forward(request, response);
    }
    
    //Clean up resources
    public void destroy() {
        logger.debug("terminando filtro");
    }
}
